﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using SpectrumAnalyser.Common.Csv;
using SpectrumAnalyser.Common.Logs;
using SpectrumAnalyser.Data.Files.SpectrumDatabaseContracts.Repository;
using SpectrumAnalyser.ModelObjects;
using SpectrumAnalyser.ModelObjects.Enum;

namespace SpectrumAnalyser.Data.Files.SpectrumDatabase.Repository
{
    public class ZaidelSpectrumLinesRepository : ISpectrumLinesRepository
    {
        public IList<Peak> FillMatchedPeaks(IList<Peak> peaks, SpectrumDbConnection connection, LinesSearchSettings linesSearchSettings)
        { 
            //if input peaks are angstroms.
            double wavelengthCoefficient = peaks.Any(x => x.Point2.X > 2000) ? 0.1 : 1;

            DataTable table = CsvReader.ReadTable(connection.ConnectionString, '\t');

            Logger.Log(DateTime.Now.ToString());

            foreach (var peak in peaks)
            {
                IList<SpectrumPoint> localMax = new List<SpectrumPoint>() { peak.Point2 };// peak.Points.Where(x => x.Y == peak.Points.MaxBy(y => y.Y).Y).ToList();
                peak.MatchedChemicalElements = peak.MatchedChemicalElements ?? new List<ChemicalElement>();

                foreach (DataRow row in table.Rows)
                {
                    double baseValue;
                    double intencity;
                    if (double.TryParse(row[0].ToString(), out baseValue) && double.TryParse(row[3].ToString(), out intencity))
                    {
                        baseValue = baseValue / wavelengthCoefficient;
                        foreach (var spectrumPoint in localMax)
                        {
                            if (Math.Abs(spectrumPoint.X - baseValue) < linesSearchSettings.PeakWavelengthRange && Math.Abs(spectrumPoint.Y - intencity) < linesSearchSettings.PeakIntensityRange)
                            {
                                int ionizationStage;
                                int.TryParse(row[2].ToString(), out ionizationStage);
                                peak.MatchedChemicalElements.Add(new ChemicalElement
                                {
                                    Name = row[1].ToString(),
                                    IonizationStage = ionizationStage,
                                    OriginalIntensity = intencity
                                });
                            }
                        }
                    }
                }
            }

            Logger.Log(DateTime.Now.ToString());
            return peaks;
        }

        public WavelengthMeasure WavelengthMeasure
        {
            get { return WavelengthMeasure.Nanometers; }
        }

        public string ConnectionType
        {
            get { return ModelObjects.Enum.ConnectionType.Zaidel.ToString(); }
        }
    }
}